using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using AudioStudio;
using GameFramework.Battle.Core;
using Gameplay.PVE.Config;
using Gameplay.PVE.Effect;
using Gameplay.PVE.Entity;
using Gameplay.PVE.Utils;
using UnityEngine;
using Yoozoo.Framework.Managers;
using Yoozoo.Gameplay.RTS;
using Yoozoo.Gta.Common;
using Yoozoo.Libs;
using Yoozoo.Managers;
using Yoozoo.Mars.Got;

namespace Gameplay.PVE.Skill
{
    public class SkillBase : IClass
    {

        protected enum ESkillState
        {
            None,
            Start,
            Storage,
            Cast,
            Recover,
        }

        private int id;
        //protected ESkillState state;
        private ESkillState _state;
        public UnitBase unit;
        protected float stateStartTime;
        public float currentTime;
        public PveSkillConfig config;
        protected List<SkillBullet> bulletList = new List<SkillBullet>();
        protected GameObject effect;
        protected float effectTime = 0.3f;
        protected float effectStartTime;
        protected float soundStartTime;
        protected int effectId;

        protected List<UnitBase> targetList = new List<UnitBase>();
        //记录每个目标被射出了多少子弹
        protected Dictionary<int, int> targetGetBullets = new Dictionary<int, int>();
        protected Dictionary<int,List<UnitBase>> childSkillTargetList = new Dictionary<int,List<UnitBase>>();
        protected List<Vector3> targetPositions = new List<Vector3>();

        public Vector3 targetPosition;
        public Vector3 targetForward;
        public UnitBase targetUnit;

        private Vector3 startPosition;

        private bool isEnd = true;
        private bool needStop = false;
        
        //protected Dictionary<int,List<bool>> bulletStateList = new Dictionary<int,List<bool>>();
        protected Dictionary<int,List<bool>> effectStateList = new Dictionary<int,List<bool>>();
        protected Dictionary<int,List<bool>> soundStateList = new Dictionary<int, List<bool>>();
        
        protected Dictionary<int,Dictionary<int,int>> bulletEffectList = new Dictionary<int,Dictionary<int,int>>();

        protected ESkillState State
        {
            get => this._state;
            set
            {
                this._state = value;
                if (unit?.Data == null)
                {
                    return;
                }
                var d = this.unit.Data;
                for (int i = 0; i < childSkills.Count; i++)
                {
                    PveBattleBulletsMgr.Ins.SetSkillCastingState(d.id, d.team, this.slotID, this.shootWaveCount,
                        value == ESkillState.Cast);

                    break;
                }
            }
        }

        //单个技能可触发的能量次数
        public int mpSlices;

        protected class SkillEffectData
        {
            public int effectId;
            public GameObject effect;
            public PveEffectController effectController;
            public float endTime;
            public RpgEffectConfig effectConfig;
        }

        protected List<SkillEffectData> effectList = new List<SkillEffectData>();
        
        protected int bulletCount = 0;

        public float startTime;

        public int skillType
        {
            set
            {
                m_skillType = value;
                if (m_skillType == 0)
                {
                    mpSlices = config.bullets.Count * unit.Data.shootTurns;
                }
                else
                {
                    mpSlices = 0;
                }
            }
            get { return m_skillType; }
        }//0 普攻 1 主动 2 被动

        private int m_skillType;
        
        protected float storageTime;
        protected float recoverTime;

        protected class ChildSkillData
        {
            public PveSkillConfig config;
            public SkillCasterBase caster;
            public Dictionary<int, int> effects;
        }
        
        protected List<ChildSkillData> childSkills = new List<ChildSkillData>();

        private Dictionary<int, int> extraElements = new Dictionary<int, int>();

        private Dictionary<int, Vector2Int> changeElements = new Dictionary<int, Vector2Int>();
        
        private Dictionary<int, int> changeBullets = new Dictionary<int, int>();

        private List<Vector3Int> bulletConfigs = new List<Vector3Int>();

        protected float timeScale = 1;
        
        public int level = 1;
        
        private PveSkillBulletConfig firstBulletConfig;
        
        private List<bool> summonStates = new List<bool>();

        public int globalSkillIndex;

        public int targetLayer = PveUtils.pveUnitLayer;

        public int shootWaveCount
        {
            get;
            private set;
        }

        public int slotID
        {
            get;
            private set;
        }

        protected class BulletData
        {
            public float startTime;
            public Vector3Int bulletConfig;
            public Vector3 effectConfig;
        }
        
        void IClass.OnReset()
        {
            Reset();
            Clear();
            isEnd = false;
            this.State = ESkillState.None;
            unit = null;
            globalSkillIndex = 0;
        }

        public void Clear()
        {
            RemoveEffect();
            for (int i = 0; i < bulletList.Count; i++)
            {
                bulletList[i].Dispose();
                ClassManager.Free(bulletList[i]);
            }
            bulletList.Clear();
            for (int i = 0; i < childSkills.Count; i++)
            {
                ClassManager.Free(childSkills[i].caster);
            }
            childSkills.Clear();
            changeElements.Clear();
            changeBullets.Clear();
            this.State = ESkillState.None;
        }

        protected virtual void Reset()
        {
            
        }

        public bool IsFinishCast()
        {
            return this.State == ESkillState.None || this.State == ESkillState.Recover;
        }

        protected SkillCasterBase GetCasterByConfig(PveSkillConfig config,int index)
        {
            SkillCasterBase caster;
            if (config.cast_type == 8)
            {
                caster = ClassManager.Get<WaveShootNew>();
            }
            else if (config.cast_type == 9)
            {
                caster = ClassManager.Get<Dash>();
            }
            else if (config.cast_type == 10)
            {
                caster = ClassManager.Get<Displacement>();
            }
            else
            {
                caster = ClassManager.Get<SkillCasterBase>();
            }

            caster.Init(this,config,index);
            return caster;
        }

        private Dictionary<int, int> GetGunEffects(PveSkillConfig config)
        {
            var dic = new Dictionary<int, int>();
            for (int i = 0; i < config.effects.Count; i++)
            {
                var effect = config.effects[i];
                if (effect.x < 0)
                {
                    dic[(int) effect.z] = (int)effect.y;
                }
            }

            return dic;
        }
        
        public void Initialize(UnitBase unit,int id,PveSkillConfig config)
        {
            this.unit = unit;
            this.id = id;
            this.config = config;
            childSkills.Clear();
            childSkills.Add(new ChildSkillData
            {
                config = config,
                caster = GetCasterByConfig(config,0),
                effects = GetGunEffects(config)
            });
            startTime = 0;
            for (int i = 0; i < config.child_skills.Count; i++)
            {
                var childConfig = PveUtils.GetSkillConfig(config.child_skills[i]);
                childSkills.Add(new ChildSkillData
                {
                    config = childConfig,
                    caster = GetCasterByConfig(childConfig,i+1),
                    effects = GetGunEffects(config)
                });
            }

            firstBulletConfig = PveUtils.GetSkillBulletConfig((int) config.bullets[0].y);
            mpSlices = 0;
            this.shootWaveCount = 0;
            this.slotID = unit.Data.skillList.IndexOf(id);

            if (unit.Data.team == 0)
                Debug.Log("[SkillLog] slot id is: " + this.slotID + " owner is: " + unit.Data.id);
        }

        public void PlayAuto()
        {
            Vector3 targetPosition = Vector3.zero;
            Vector3 targetForward = Vector3.zero;
            List<UnitBase> targetList = null;

            targetList = GetTargetList(config);
            if (targetList.Count > 0)
            {
                targetPosition = targetList[0].Data.position;
                targetForward = targetPosition - unit.Data.position;
            }
           
            
            Play(targetPosition,targetForward,targetList,true);
        }

        private void AddAdditiveElements()
        {
            for (int i = 0; i < childSkills.Count; i++)
            {
                var config = childSkills[i].config;
                for (int j = 0; config.additive_elements != null && j < config.additive_elements.Count; j++)
                {
                    var elementConfig = PveUtils.GetSkillElementConfig(config.additive_elements[j]);
                    if (elementConfig != null)
                    {
                        var arg = ClassManager.Get<AddElementArg>();
                        arg.source = unit;
                        arg.target = unit;
                        arg.elementConfig = elementConfig;
                        arg.isCrit = false;
                        arg.id = config.additive_elements[j];
                        arg.isSkillAdditive = true;
                        arg.sourceSkill = this;
                        unit.Transmit(ETransmitType.AddElement,arg);
                        ClassManager.Free(arg);
                    }
                }
            }
        }

        public void Play(Vector3 targetPosition,Vector3 targetForward,List<UnitBase> targetUnits = null,bool isAutoUse = false)
        {
            AddAdditiveElements();
            targetGetBullets.Clear();
            this.shootWaveCount++;
            targetLayer = PveUtils.pveUnitLayer;
            timeScale = 1;
            storageTime = config.storage_time;
            recoverTime = config.attack_recover_time;
            startTime = TimeManager.logicTime;
            needStop = false;
            bulletCount = 0;
            isEnd = false;
            //unit.Data.SetTargetForward(targetForward);
            this.targetPosition = targetPosition;
            this.targetForward = targetForward;
            effectStateList.Clear();
            soundStateList.Clear();
            childSkillTargetList.Clear();
            for (int i = 0; i < childSkills.Count; i++)
            {
                var bulletStateList = new List<bool>();
                var config = childSkills[i].config;
                var caster = childSkills[i].caster;
                caster.Prepare();
                caster.SetTargets(GetTargetList(config, targetUnits));
                //this.bulletStateList.Add(config.id,bulletStateList);
                
                var effectStateList = new List<bool>();
                for (int j = 0; config.effects != null && j < config.effects.Count; j++)
                {
                    effectStateList.Add(false);
                }
                this.effectStateList.Add(config.id,effectStateList);
                
                var soundStateList = new List<bool>();
                for (int j = 0; config.sound_name != null && j < config.sound_name.Count; j++)
                {
                    soundStateList.Add(false);
                }
                this.soundStateList.Add(config.id,soundStateList);

                childSkillTargetList.Add(i,GetTargetList(config,targetUnits));
            }

            targetList = childSkillTargetList[0];
            if (targetList.Count > 0 && isAutoUse && (firstBulletConfig != null && firstBulletConfig.director_type != -1) || (skillType == 0 && config.search_sort == 10))
            {
                this.targetUnit = targetList[0];
                //this.targetPosition = targetList[0].Data.position;
                var distanceLimit = 0f;
                /*if (skillType == 0)
                {
                    distanceLimit = unit.Data.attackRange;
                }*/
                this.targetPosition =
                    PveTargetSearchHelper.GetAutoSkillPosition(ref targetList, firstBulletConfig, unit,
                        config.search_sort,distanceLimit);
                if (config.search_sort == 3)
                {
                    this.targetPosition = unit.Data.position;
                }
            }

            if (targetList.Count == 0 && isAutoUse)
            {
                ForceStop();
                return;
            }

            targetPositions.Clear();
            if (config.bullets.Count > 0)
            {
                if (firstBulletConfig != null && firstBulletConfig.director_type == 5) //范围内随机圆
                {
                    var center = this.targetPosition;
                    var range = firstBulletConfig.director_args["radius"];
                    var smallRadius = firstBulletConfig.director_args["smallRadius"];
                    
                    //范围内随机圆，可重叠，尽量不重叠
                    //小圆的位置 
                    float near = 0;
                    float far = range - smallRadius;
                    //希望小圆距离大圆的中心是随机值，但又不是均匀随机，离得越远随机到的概率越大。
                    
                    //随机函数y = x3
                    int sliceCount = 10;
                    List<float> regionPoints = new List<float>();
                    //先分成10份，获得每个区间对应的权重
                    float eachSlice = 1f / sliceCount;
                    float totalValue = 0;
                    for (int i = 0; i <= sliceCount; i++)
                    {
                        var value = (eachSlice * i) * (eachSlice * i) * (eachSlice * i);
                        totalValue += value;
                        regionPoints.Add(totalValue);
                    }
                    
                    float startAngle = Random.Range(0, 360);
                    float angleInterval = 360f / config.bullets.Count;
                    var eachSliceDistance = (far - near) / sliceCount;
                    for (int i = 0; i < config.bullets.Count; i++)
                    {
                        float value = Random.Range(0, totalValue);
                        float x = near;
                        for (int j = 0; j < regionPoints.Count; j++)
                        {
                            if (value > regionPoints[j])
                            {
                                
                            }
                            else
                            {
                                if (j == 0)
                                {
                                    x = near;
                                }
                                else
                                {
                                    var left = near + eachSliceDistance * j;
                                    var right = near + eachSliceDistance * (j + 1);
                                    var percent = Mathf.InverseLerp(regionPoints[j - 1], regionPoints[j], value);
                                    x = Mathf.Lerp(left, right, percent);
                                    break;
                                }
                            }
                        }
                       
                        var position = center + Quaternion.AngleAxis(startAngle, Vector3.up) * Vector3.forward * x;
                        targetPositions.Add(position);
                        startAngle += angleInterval;
                    }
                    
                    //范围内随机圆，必须不重叠
                    
                }
            }

            
            RemoveEffect();
            
            
            this.State = ESkillState.Start;
            //if (this is SkillShootMove)
            {
                
            }
            //else
            if (this is SkillAuto)
            {
                
            }
            else if (unit.Data.moveState != 1)
            {
                //unit.Play("Idle");
            }
            

            /*state = ESkillState.MoveTo;
            this.targetPosition = this.targetUnit.Data.position - this.targetUnit.Data.forward * 0.5f;
            StartMoveTo();*/
            currentTime = TimeManager.logicTime;
            effectStartTime = currentTime;
            soundStartTime = currentTime;
            stateStartTime = currentTime;

            if (firstBulletConfig.director_type != 6)
            {
                unit.Data.SetTargetForward(targetForward);
            }
            

            if (config.type == 1 && !isAutoUse)
            {
                /*if (unit.Data.modelId == 1000)
                {
                    if (!PveUtils.HasShownSkillVideo)
                    {
                        //PveManager.Instance.ShowSkillVideo();
                        PveUtils.HasShownSkillVideo = true;
                    }
                    else
                    {
                        TimeManager.gameTimeScale = PveManager.Instance.TimeSpeed;
                        PveEffectManager.Instance.HideBlackScreen();
                    }

                }
                else*/
                /*{
                    TimeManager.gameTimeScale = PveManager.Instance.TimeSpeed;
                    PveEffectManager.Instance.HideBlackScreen();
                }*/
                /*if (!string.IsNullOrEmpty(PveGlobalVlues.defaultSkillCameraName))
                {
                    PveManager.Instance.ShowSkillDisplay(unit as  BattleUnit,this,PveGlobalVlues.defaultSkillCameraName);
                }
                else */if (!string.IsNullOrEmpty(config.camera_animation))
                {
                    
                }

            }

            
            if (this is SkillInitiative)
            {
                if (unit.Data.team == 0)
                {
                    PveEffectManager.Instance.PlayEffect((int)ESkillEffect.skillCastEffect2,unit.Data.position + new Vector3(0,1,0),unit.Data.forward,5,1,unit.gameObject.transform);
                }
                
                if (unit.Data.isManualMoving)
                {
                    //PveCameraManager.Instance.RpgSkill();
                }

                if (unit.Data.rpgSkillId == config.id)
                {
                    unit.Transmit(ETransmitType.ShowSkillModel);
                }

                if (unit.Data.team == 0)
                {
                    ResidentHandler.Inst.GetFunction("pveManager.ShowCastSkill").Action(config.id);
                }
            }
            else if (isAutoUse)
            {
                //PveEffectManager.Instance.PlayEffect((int)ESkillEffect.skillCastEffect,unit.Data.position,unit.Data.forward);
            }
            summonStates.Clear();
            if (config.summon_id != 0)
            {
                summonConfig = PveUtils.GetRpgSummonConfig(config.summon_id);
                for (int i = 0; i < summonConfig.positions.Count; i++)
                {
                    summonStates.Add(false);
                }
            }
            else
            {
                summonConfig = null;
            }

           
            
            Start();
            unit.Data.isApplyAnimationMovement = config.apply_movement == 1;
        }

        protected virtual void Start()
        {
            unit.Data.attackState = 1;
        }
        
        //开始释放
        protected virtual void Cast()
        {
            for (int i = 0; i < childSkills.Count; i++)
            {
                childSkills[i].caster.Start(stateStartTime);
            }
        }
        
        //开始蓄力
        protected virtual void Storage()
        {
            
        }

        protected virtual void StartMoveTo()
        {
            startPosition = unit.Data.position;
            /*unit.Play("Run",5);
            unit.Transmit(ETransmitType.ShowGhostShadow);*/
        }
        
        //移动
        protected virtual void MoveTo()
        {
            /*if (Vector3.Distance(targetPosition, unit.Data.position) <= config.moveSpeed * Time.deltaTime)
            {
                unit.Transmit(ETransmitType.HideGhostShadow);
                state = ESkillState.Storage;
                unit.Data.SetTargetForward(targetUnit.Data.position - unit.Data.position);
                unit.Data.forward = unit.Data.targetForward;
                //Debug.LogError(unit.Data.forward);
                Storage();
            }
            else
            {
                var speed = config.moveSpeed * Time.deltaTime * (targetPosition - unit.Data.position).normalized;
                unit.Data.position += speed;
            }*/
            unit.Data.position = targetPosition;
            this.State = ESkillState.Storage;
            unit.Data.SetTargetForward(targetUnit.Data.position - unit.Data.position);
            unit.Data.forward = unit.Data.targetForward;
            Storage();
        }

        protected virtual void StartMoveBack()
        {
            /*unit.Play("Run",5);
            unit.Transmit(ETransmitType.ShowGhostShadow);*/
        }

        protected virtual void MoveBack()
        {
            /*if (Vector3.Distance(startPosition, unit.Data.position) <= config.moveSpeed * Time.deltaTime)
            {
                unit.Transmit(ETransmitType.HideGhostShadow);
                //unit.Data.forward = lock.Data.position - unit.Data.position;
                Recover();
                state = ESkillState.None;
            }
            else
            {
                var speed = config.moveSpeed * Time.deltaTime * (startPosition - unit.Data.position).normalized;
                unit.Data.SetTargetForward(startPosition - unit.Data.position);
                unit.Data.forward = unit.Data.targetForward;
                unit.Data.position += speed;
                
            }*/
            unit.Data.position = startPosition;
            Recover();
            this.State = ESkillState.None;
        }

        protected virtual bool CheckHasAmmo()
        {
            return unit.Data.leftAmmoCount > 0 || unit.Data.leftAmmoCount == -1;
        }
        
        protected virtual void StartRecover()
        {
            this.State = ESkillState.Recover;
            stateStartTime = currentTime;
            for (int i = 0; i < childSkills.Count; i++)
            {
                childSkills[i].caster.End();
            }
        }

        public void StartRecoverFromExternal()
        {
            StartRecover();
        }
        
        //技能结束
        protected virtual void Recover()
        {
            if (this is SkillInitiative)
            {
                if (unit.Data.isManualMoving)
                {
                    //PveCameraManager.Instance.RpgSkillEnd();
                }
                unit.Transmit(ETransmitType.HideSkillModel);
            }

            PveFlyTextManager.Instance.SkillEnd(this);
            unit.Data.isApplyAnimationMovement = false;
            unit.Data.attackState = 0;
            unit.Play("RefreshIdle");
        }

        protected virtual void RecoverEvent()
        {
            
        }

        protected virtual void StorageEvent()
        {
            
        }

        public void DoStartCast()
        {
            stateStartTime = currentTime;
        }
        
        public virtual void DoCastEvent()
        {
            CastEvent();
        }
        
        protected virtual void CastEvent()
        {
            for (int i = 0; i < childSkills.Count; i++)
            {
                childSkills[i].caster.Update(currentTime);
            }
        }

        protected virtual void CastEvent(PveSkillConfig config,int childSkillIndex)
        {
            /*var bulletStateList = this.bulletStateList[config.id];
            for (int i = 0; i < config.bullets.Count; i++)
            {
                if (!bulletStateList[i] && config.bullets[i].z >= 0 && currentTime - stateStartTime >= config.bullets[i].x / 30f)
                {
                    //PlayBulletSound();
                    var offset = GetBulletOffset((int)config.bullets[i].z);
                    var bulletConfig = PveUtils.GetSkillBulletConfig((int) config.bullets[i].y);
                    if (bulletConfig.director_type == 5)//按照之前随机的方向
                    {
                        CreateBulletToTargetPosition(i,offset,(int)config.bullets[i].y,childSkillIndex,config.bullets[i].z);
                    }
                    else if (bulletConfig.director_type == 4 || bulletConfig.director_type == 0 || bulletConfig.damage_type == 1)//向targetList方向
                    {
                        CreateBulletByTargets(offset,(int)config.bullets[i].y,childSkillIndex,config.bullets[i].z,i);
                    }
                    else if (bulletConfig.director_type == 6)
                    {
                        CreateBulletBySngleTarget(offset,(int)config.bullets[i].y,childSkillIndex,config.bullets[i].z,i);
                    }
                    else//向自身方向
                    {
                        CreateBulletByCertainForward(offset,(int)config.bullets[i].y,childSkillIndex,config.bullets[i].z);
                    }
                    bulletStateList[i] = true;
                }
            }*/
        }


        public virtual void End()
        {
            this.State = ESkillState.None;
            isEnd = true;
            this.targetUnit = null;
            unit.Play("Idle");
        }

        protected void RemoveEffect()
        {
            if (effect != null)
            {
                PveResourceManager.RecoverResource(effect,PveResourceManager.EPveResType.SkillEffect, effectId);
                effect = null;
            }

            for (int i = 0; i < effectList.Count; i++)
            {
                var data = effectList[i];
                PveResourceManager.RecoverResource(data.effect,PveResourceManager.EPveResType.SkillEffect,data.effectId);
            }
            effectList.Clear();
        }

        public void DestroyBullets()
        {
            for (int i = 0; i < bulletList.Count; i++)
            {
                bulletList[i].Dispose();
                ClassManager.Free(bulletList[i]);
            }
            bulletList.Clear();
        }
        
        public void Stop()
        {
            needStop = true;
            //unit.Log("StopSkill"+config.id);
            /*state = ESkillState.None;
            Recover();
            End();*/
        }

        public void ForceStop()
        {
            this.State = ESkillState.None;
            isEnd = true;
            unit.Data.SetIsInAttack(false);
            unit.Data.SetIsInSkill(false);
            unit.Data.SetIsCanMove(true);
            unit.Data.attackState = 0;
            //unit.Log("ForceStop"+config.id);
            OnForceStop();
            OnStop();
        }

        protected virtual void OnForceStop()
        {
            
        }

        protected virtual void OnStop()
        {
            for (int i = 0; i < effectList.Count; i++)
            {
                var effectData = effectList[i];
                if (effectData.effectConfig != null && effectData.effectConfig.life_time_type == 1)
                {
                    PveResourceManager.RecoverResource(effectData.effect,PveResourceManager.EPveResType.SkillEffect,effectData.effectId);
                    effectList.RemoveAt(i);
                    i--;
                }
            }

            if (summonConfig != null && summonConfig.type == 0)
            {
                var config = PveUtils.GetRpgMonsterConfig(summonConfig.summon_id);
                var modelConfig = PveUtils.GetRpgModelConfig(config.model_id);
                UnitManager.Instance.RemoveSummonDic(globalSkillIndex, modelConfig.res_id);
            }

            var skillEndArg = ClassManager.Get<SkillEndArg>();
            skillEndArg.skill = this;
            unit.Transmit(ETransmitType.OnSkillEnd,skillEndArg);
            ClassManager.Free(skillEndArg);
            
            for (int i = 0; i < childSkills.Count; i++)
            {
                childSkills[i].caster.ForceEnd();
            }
            if (!string.IsNullOrEmpty(config.camera_animation))
            {
                
            }
            unit.Play("RefreshIdle");
        }

        public void RemoveAllBullets()
        {
            for (int i = 0; i < bulletList.Count; i++)
            {
                ClassManager.Free(bulletList[i]);
            }
            bulletList.Clear();
        }

        protected virtual bool CheckIsCanSkill()
        {
            return !unit.Data.isDead;// && unit.Data.IsInitiative();
        }

        public void CreateBulletByCertainForward(Vector3 offset,int bulletId,int childSkillIndex = 0,int gunPointIndex = 0)
        {
            var bullet = GetBullet(bulletId,offset,Vector3.zero,targetUnit,childSkillIndex,gunPointIndex);
            bullet.CheckStartHit();
            bulletList.Add(bullet);
        }
        
        public void CreateBulletByRotation(Vector3 offset,Vector3 rotation,int bulletId,int childSkillIndex = 0,int gunPointIndex = 0)
        {
            var bullet = GetBullet(bulletId,offset,rotation,targetUnit,childSkillIndex,gunPointIndex);
            bullet.CheckStartHit();
            bulletList.Add(bullet);
        }

        public void CreateBulletByTargets(Vector3 offset,int bulletId,int childSkillIndex = 0,int gunPointIndex = 0,int bulletIndex = 0)
        {
            var targetList = this.targetList;
            if (childSkillIndex >= 0)
            {
                targetList = childSkillTargetList[childSkillIndex];
            }

            if (targetList.Count == 0)
            {
                if (PveTargetSearchHelper.CheckIsInTagList(unit, unit, config))
                {
                    targetList.Add(unit);
                }

                if (targetList.Count == 0)
                {
                    Debug.Log(config.id + " 目标为空");
                }
            }
            for (int i = 0; i < targetList.Count; i++)
            {
                var target = targetList[i];
                float rotation = PveUtils.GetAngle(unit.Data.forward,target.Data.position - unit.Data.position);
                var bullet = GetBullet(bulletId,offset,Vector3.zero,targetList[i],childSkillIndex,gunPointIndex,bulletIndex);
                bullet.CheckStartHit();
                bulletList.Add(bullet);
            }
        }
        
        public void CreateBulletBySngleTarget(Vector3 offset,int bulletId,int childSkillIndex = 0,int gunPointIndex = 0,int bulletIndex = 0)
        {
            var targetList = this.targetList;
            var config = this.config;
            if (childSkillIndex >= 0)
            {
                targetList = childSkillTargetList[childSkillIndex];
                config = childSkills[childSkillIndex].config;
            }

            if (targetList.Count == 0)
            {
                if (PveTargetSearchHelper.CheckIsInTagList(unit, unit, config))
                {
                    targetList.Add(unit);
                }

                if (targetList.Count == 0)
                {
                    Debug.Log(config.id + " 目标为空");
                }
            }
            for (int i = 0; i < targetList.Count; i++)
            {
                var target = targetList[i];

                if (config.single_max_bullet > 0)
                {
                    if (!targetGetBullets.TryGetValue(target.Data.id, out var count))
                    {
                        targetGetBullets[target.Data.id] = 1;
                    }
                    else
                    {
                        if (count >= config.single_max_bullet)
                        {
                            continue;
                        }
                        targetGetBullets[target.Data.id] = count + 1;
                    }
                }
                
                float rotation = PveUtils.GetAngle(unit.Data.forward,target.Data.position - unit.Data.position);
                var bullet = GetBullet(bulletId,offset,Vector3.zero,target,childSkillIndex,gunPointIndex,bulletIndex);
                bullet.CheckStartHit();
                bulletList.Add(bullet);
                break;
            }
        }

        public void CreateBulletToTargetPosition(int bulletIndex,Vector3 offset,int bulletId,int childSkillIndex = 0,int gunPointIndex = 0)
        {
            //var originTarget = targetPosition;
            //for (int i = 0; i < targetPositions.Count; i++)
            {
                targetPosition = targetPositions[bulletIndex];
                float rotation = PveUtils.GetAngle(unit.Data.forward,targetPosition - unit.Data.position);
                var bullet = GetBullet(bulletId,offset,Vector3.zero,null,childSkillIndex,gunPointIndex);
                bullet.CheckStartHit();
                bulletList.Add(bullet);
            }
            //targetPosition = originTarget;
        }

        //由其他子弹产生的效果
        public void CreateSubBullet(Vector3 position,int bulletId)
        {
            var bullet = GetBullet(bulletId, Vector3.zero,Vector3.zero, null);
            if (bullet is Area area)
            {
                area.SetTargetPositionAndForward(position,position,targetForward);
            }
            bulletList.Add(bullet);
        }

        private int SortDistance(UnitBase a,UnitBase b)
        {
            return Vector3.Distance(a.Data.position, unit.Data.position)
                .CompareTo(Vector3.Distance(b.Data.position, unit.Data.position));
        }
        
        private int SortDistanceFar(UnitBase a,UnitBase b)
        {
            return Vector3.Distance(b.Data.position, unit.Data.position)
                .CompareTo(Vector3.Distance(a.Data.position, unit.Data.position));
        }

        private int SortHpMin(UnitBase a, UnitBase b)
        {
            return (a.Data.CurrentHp / a.Data.TotalHp).CompareTo(b.Data.CurrentHp / b.Data.TotalHp);
        }
        
        private int SortHpMax(UnitBase a, UnitBase b)
        {
            return (b.Data.CurrentHp / b.Data.TotalHp).CompareTo(a.Data.CurrentHp / a.Data.TotalHp);
        }
        
        //如果是自动技能，则自动选择目标
        //如果是外部触发类技能，则优先判断是否有外部传入目标，没有的话就自动选择目标
        //如果是手动技能，选择外部传入目标
        protected List<UnitBase> GetTargetList(PveSkillConfig config,List<UnitBase> targetUnits = null)
        {
            List<UnitBase> targetList = new List<UnitBase>();
            if (targetUnits != null)
            {
                for (int i = 0; i < targetUnits.Count; i++)
                {
                    var candidate = targetUnits[i];
                    if (PveTargetSearchHelper.CheckIsInTagList(this.unit, candidate, config))
                    {
                        targetList.Add(candidate);
                    }
                }

                if (targetList.Count > 0)
                {
                    return targetList;
                }
            }

            if (skillType == 0) //普攻直接找自己的索敌目标
            {
                if (config.search_sort == 10)
                {
                    List<UnitBase> list = new List<UnitBase>();
                    PveTargetSearchHelper.GetCandidates(this.unit,config,ref list);
                    return list;
                }
                else
                {
                    targetList.Add(unit.Data.lockTarget);
                    return targetList;
                }
            }
            
            List<UnitBase> candidatelist = new List<UnitBase>();
            PveTargetSearchHelper.GetCandidates(this.unit,config,ref candidatelist);
            
            for (int i = 0; i < candidatelist.Count; i++)
            {
                targetList.Add(candidatelist[i]);
            }

            if (config.search_sort == 0)
            {
                targetList.Sort(SortDistance);
                for (int i = 0; i < targetList.Count; i++)
                {
                    var target = targetList[i];
                    if (config.search_team == 0 && target == this.unit.Data.lockTarget || config.search_team == 1 && target == this.unit)
                    {
                        targetList.RemoveAt(i);
                        targetList.Insert(0,target);
                        break;
                    }
                }
            }
            else if (config.search_sort == 1)
            {
                targetList.Sort(SortDistanceFar);
            }
            else if (config.search_sort == 5)
            {
                BattleUtils.Shuffle(ref targetList);
            }

            var searchCount = config.search_count;
            if (searchCount > 0)
            {
                int rest = targetList.Count - config.search_count;
                for (int i = 0; i < rest; i++)
                {
                    targetList.RemoveAt(targetList.Count - 1);
                }
            }

            if (targetList.Count == 0)
            {
#if UNITY_EDITOR
                Debug.LogError(config.id + " 的目标数目为0");
#else
                Debug.Log(config.id + " 的目标数目为0");
#endif
            }
            return targetList;
        }
        
        protected SkillBullet GetBullet(int id,Vector3 offset,Vector3 forward,UnitBase targetUnit,int childIndex = 0,int gunPointIndex = 0,int bulletIndex = 0)
        {
            if (changeBullets.TryGetValue(id, out var newId))
            {
                id = newId;
            }
            var config = PveUtils.GetSkillBulletConfig(id);
            SkillBullet bullet = null;
            var childSkillConfig = childSkills[childIndex].config;

            if (config.damage_type == 0)
            {
                bullet = ClassManager.Get<SkillBullet>();
            }
            else if (config.damage_type == 1)
            {
                bullet = ClassManager.Get<TrackBullet>();
                bullet.SetSource(unit);
                ((TrackBullet)bullet).SetTarget(config,targetUnit);
            }
            else if (config.damage_type == 2 || config.damage_type == 4)
            {
                bullet = ClassManager.Get<Wave>();
                bullet.SetTargetAndDirector(targetPosition,firstBulletConfig.director_type,firstBulletConfig.director_args);
            }
            else if (config.damage_type == 3)
            {
                bullet = ClassManager.Get<Grenade>();
                var targetPosition = this.targetPosition;
                if (targetUnit != null)
                {
                    targetPosition = targetUnit.Data.position;
                }
                bullet.SetTargetAndDirector(targetPosition,firstBulletConfig.director_type,firstBulletConfig.director_args);
                var gunPointParent = unit.gameObject.transform;
                if (unit.Data.gunPoints.Count > gunPointIndex)
                {
                    gunPointParent = unit.Data.gunPoints[gunPointIndex];
                }
                ((Grenade)bullet).SetStartParentAndTargets(gunPointParent,targetList);
            }
            else if (config.damage_type == 5)
            {
                bullet = ClassManager.Get<TrackRocket>();
                ((TrackRocket)bullet).SetTargetAndIndex(targetUnit,bulletIndex);
            }
            else if (config.damage_type == 6)
            {
                bullet = ClassManager.Get<Area>();
                ((Area)bullet).SetTargetPositionAndForward(unit.Data.position,targetPosition,targetForward);
            }
            else if (config.damage_type == 7)
            {
                bullet = ClassManager.Get<DynamicObstacle>();
                ((DynamicObstacle)bullet).SetTargetPositionAndForward(targetPosition,targetForward);
            }
            else if (config.damage_type == 8)
            {
                bullet = ClassManager.Get<Summon>();
                ((Summon)bullet).SetTarget(targetUnit);
            }
            else
            {
                return null;
            }

            var position = unit.Data.position;
            var angle = unit.gameObject.transform.localEulerAngles;
            Vector3 bulletForward = unit.gameObject.transform.forward;
            if (config.damage_type == 0)
            {
                if (targetUnit != null && targetUnit.Data.hitPoints != null && targetUnit.Data.hitPoints.Count > 0)
                {
                    var targetPos = targetUnit.Data.hitPoints[Random.Range(0,targetUnit.Data.hitPoints.Count)].position;
                    bulletForward = targetPos - unit.Data.position - offset;
                }
            }

            if (this.config.bullet_birth_rotation != null && this.config.bullet_birth_rotation.Count > 0)
            {
                float rot;
                float rotx;
                if (this.config.bullet_birth_rotation.Count > bulletCount)
                {
                    rot = this.config.bullet_birth_rotation[bulletCount].y;
                    rotx = this.config.bullet_birth_rotation[bulletCount].x;
                }
                else
                {
                    rot = this.config.bullet_birth_rotation[bulletCount % this.config.bullet_birth_rotation.Count].y;
                    rotx = this.config.bullet_birth_rotation[bulletCount % this.config.bullet_birth_rotation.Count].y;
                }
                //rot *= Random.Range(0.8f, 1.2f);
                bulletForward = Quaternion.AngleAxis(rot, Vector3.up) *
                                bulletForward;
                bulletForward = Quaternion.AngleAxis(rotx, unit.Data.forward) * bulletForward;
                forward = bulletForward;
            }

            angle = Quaternion.FromToRotation(Vector3.forward, bulletForward).eulerAngles;
            //angle += rotation;
            if (forward != Vector3.zero)
            {
                angle = Quaternion.FromToRotation(Vector3.forward, forward).eulerAngles;
            }
            
            bullet.Initialize(config,childSkillConfig,this,position,offset,angle,unit);
            bulletCount++;
            
            //如果子弹有额外元素，则添加
            if (extraElements.ContainsKey(id))
            {
                bullet.AddExtraElement(extraElements[id]);
            }
            
            //检查是否有元素需要被替换
            if (changeElements.ContainsKey(id))
            {
                bullet.ChangeElement((int)changeElements[id].x,(int)changeElements[id].y);
            }

            unit.Transmit(ETransmitType.CreateBullet);
            
            //检测是否需要展示枪口特效
            if (childSkills[childIndex].effects.TryGetValue(bulletIndex, out var effectId))
            {
                var pos = unit.Data.position;
                var effectForward = unit.Data.forward;
                Transform gunPoint = null;
                if (effectId != 0)
                {
                    if (unit.Data.gunPoints.Count > gunPointIndex)
                    {
                        pos = unit.Data.gunPoints[gunPointIndex].position;
                        effectForward = unit.Data.gunPoints[gunPointIndex].forward;
                    }
                    else
                    {
                        pos = unit.Data.gunPoints[0].position;
                        effectForward = unit.Data.gunPoints[0].forward;
                    }
                
                    PveEffectManager.Instance.PlayEffect(effectId,pos,effectForward);
                }
                ShowBulletCase(pos,id,gunPointIndex);
            }
            return bullet;
        }

        public void Update()
        {
           
            {
                Update(TimeManager.LogicDeltaTime);
            }
        }

        protected bool CheckIsCasting()
        {
            for (int i = 0; i < childSkills.Count; i++)
            {
                if (childSkills[i].caster.IsCasting())
                {
                    return true;
                }
            }
            return false;
        }
        
        protected virtual bool CastEndCondition()
        {
            return currentTime - stateStartTime >= config.attack_cast_time;
        }
        
        protected void Update(float deltaTime)
        {
            if (CheckIsCanSkill())
            {
                if (this.State == ESkillState.Start)
                {
                    if (currentTime > stateStartTime)
                    {
                        this.State = ESkillState.Storage;
                        Storage();
                        stateStartTime = currentTime;
                    }
                    
                }
                if (this.State == ESkillState.Storage)
                {
                    if (currentTime - stateStartTime >= storageTime && (unit.Data.forward - unit.Data.targetForward).sqrMagnitude <= 0.01f)
                    {
                        //if (CheckHasAmmo())
                        {
                            this.State = ESkillState.Cast;
                            stateStartTime = currentTime;
                            Cast();
                        }
                        /*else
                        {
                            unit.Transmit(ETransmitType.Reload);
                        }*/
                    }
                    else
                    {
                        StorageEvent();
                    }
                    
                }
                else if (this.State == ESkillState.Cast)
                {
                    CastEvent();
                    if (!CheckIsCasting() && CastEndCondition() || needStop)
                    {
                        StartRecover();
                    }
                }
                else if (this.State == ESkillState.Recover)
                {
                    RecoverEvent();
                    if (currentTime - stateStartTime >= recoverTime)
                    {
                        Recover();
                        this.State = ESkillState.None;
                    }
                }
            }

            /*if (effectStartTime != 0 && currentTime - effectStartTime > effectTime)
            {
                RemoveEffect();
                effectStartTime = 0;
            }*/
            
            for (int i = 0; i < bulletList.Count; i++)
            {
                if (bulletList[i].IsDisposed)
                {
                    ClassManager.Free(bulletList[i]);
                    bulletList.RemoveAt(i);
                    i--;
                }
                else if (bulletList[i].IsBornThisFrame)
                {
                    bulletList[i].IsBornThisFrame = false;
                    bulletList[i].Update(0);
                }
                else
                {
                    bulletList[i].Update(deltaTime);
                }
            }

            for (int i = 0; i < bulletList.Count; i++)
            {
                bulletList[i].UpdateTime(deltaTime);
            }
            UpdateEffect();

            /*if (bulletList.Count == 0 && !isEnd && (state == ESkillState.None))
            {
                Stop();
            }*/
            /*else if (!isEnd && (unit.Data.lockTarget == null || (unit.Data.lockTarget != null && unit.Data.lockTarget.Data.isDead)))
            {
                unit.Data.lockTarget = null;
                Stop();
            }*/
            currentTime += deltaTime * timeScale;
        }

        public Vector3 GetBulletOffset(int index)
        {
            int bulletPosIndex = index;
            Vector3 offset = Vector3.zero;
            if (unit.Data.gunPoints.Count > bulletPosIndex)
            {
                offset = unit.Data.gunPoints[bulletPosIndex].position - unit.Data.position;
            }
            else if (unit.Data.gunPoints.Count > 0)
            {
                offset = unit.Data.gunPoints[0].position - unit.Data.position;
            }
            return offset;
        }

        protected void PlayBulletSound()
        {
            if (config.sound_name != null && config.sound_name.Count > 0)
            {
                AudioManager.PlaySound(config.sound_name[0],unit.gameObject);
            }
        }

        protected virtual void UpdateSound(PveSkillConfig config)
        {
            var soundStateList = this.soundStateList[config.id];
            for (int i = 0; config.sound_name != null && i < config.sound_name.Count; i++)
            {
                var soundFrame = 0;
                var soundType = 0;
                if (config.sound_frame.Count > i)
                {
                    soundFrame = config.sound_frame[i].x;
                    soundType = config.sound_frame[i].z;
                }
                if (!soundStateList[i] && currentTime - soundStartTime >= soundFrame / 30f)
                {
                    if (soundType == 0)
                    {
                        AudioManager.PlaySound(config.sound_name[i],unit.gameObject);
                    }
                    else
                    {
                        AudioManager.PlayVoice(config.sound_name[i],unit.gameObject);
                    }
                    soundStateList[i] = true;
                }
            }
        }
        
        protected virtual void UpdateEffect(PveSkillConfig config)
        {
            if (config.effects == null)
            {
                return;
            }
            var effectStateList = this.effectStateList[config.id];
            for (int i = 0; i < config.effects.Count; i++)
            {
                if (config.effects[i].x < 0)
                {
                    continue;
                }
                if (!effectStateList[i] && currentTime - effectStartTime > (config.effects[i].x + 1) / 30f)
                {
                    Vector3 position = unit.Data.position;
                    Vector3 forward = unit.Data.forward;
                    Transform parent = null;
                    if (unit.Data.skillEffectPoints.Count > config.effects[i].z)
                    {
                        position = unit.Data.skillEffectPoints[(int)config.effects[i].z].position;
                        var effectConfig = PveUtils.GetRpgEffectConfig((int) config.effects[i].y);
                        if (effectConfig.use_parent_forward == 1)
                        {
                            forward = unit.Data.skillEffectPoints[(int) config.effects[i].z].forward;
                        }

                        if (effectConfig.set_parent == 1)
                        {
                            parent = unit.Data.skillEffectPoints[(int) config.effects[i].z];
                        }
                        //parent = unit.Data.skillEffectPoints[(int) config.effects[i].z];
                        //forward = unit.Data.skillEffectPoints[(int)config.effects[i].z].forward;
                    }
                    
                    int effectId = (int) config.effects[i].y;
                    var scale = 0f;
                    if (unit.renderer != null)
                    {
                        scale = unit.renderer.transform.localScale.x / unit.Data.rendererOriginScale.x;
                    }
                    var effect = PveEffectManager.Instance.PlayEffect2((int)config.effects[i].y,position,forward,scale, parent);
                    if (effect != null)
                    {
                        SetEffectLayer(effect,targetLayer);
                        float endTime = 5 + currentTime;
                        var effectConfig = PveUtils.GetRpgEffectConfig((int) config.effects[i].y);
                        effectList.Add(new SkillEffectData
                        {
                            effect = effect,
                            effectId = effectId,
                            endTime = endTime,
                            effectController = effect.GetComponent<PveEffectController>(),
                            effectConfig = effectConfig,
                        });
                        effectStateList[i] = true;
                    }
                }
            }

            for (int i = 0; i < effectList.Count; i++)
            {
                var effectData = effectList[i];
                if (currentTime >= effectData.endTime)
                {
                    var controller = effectData.effectController;
                    if (controller != null)
                    {
                        controller.SetSpeed(1);
                    }
                    PveResourceManager.RecoverResource(effectData.effect,PveResourceManager.EPveResType.SkillEffect,effectData.effectId);
                    effectList.RemoveAt(i);
                    i--;
                }
            }
        }

        protected void SetEffectLayer(GameObject obj,int layer)
        {
            var effectController = obj.GetComponent<PveEffectController>();
            effectController.SetLayer(layer);
        }
        
        private float nextShootTime = 0;
        //扫射逻辑
        protected void UpdateWaveShoot(PveSkillConfig config)
        {
            float interval = config.GetCastParam(0);
            var firstBulletConfig = PveUtils.GetSkillBulletConfig(config.bullets[0].y);
            if (nextShootTime == 0 || TimeManager.logicTime >= nextShootTime)
            {
                var offset = GetBulletOffset((int)config.bullets[0].z);
                var bulletConfig = PveUtils.GetSkillBulletConfig((int) config.bullets[0].y);
                if (firstBulletConfig.director_type == 5)//按照之前随机的方向
                {
                    CreateBulletToTargetPosition(0,offset,(int)config.bullets[0].y,0,config.bullets[0].z);
                }
                else if (firstBulletConfig.director_type == 4 || firstBulletConfig.director_type == 0 || bulletConfig.damage_type == 1)//向targetList方向
                {
                    CreateBulletByTargets(offset,(int)config.bullets[0].y,0,config.bullets[0].z);
                }
                else if (bulletConfig.director_type == 6)
                {
                    CreateBulletBySngleTarget(offset,(int)config.bullets[0].y,0,config.bullets[0].z);
                }
                else//向自身方向
                {
                    float rotation = PveUtils.GetAngle(unit.Data.forward,new Vector3(offset.x,0,offset.z));
                    var forward = new Vector3(offset.x, Random.Range(-0.05f, 0.05f), offset.z);
                    CreateBulletByRotation(offset,forward,(int)config.bullets[0].y,0,config.bullets[0].z);
                }
                nextShootTime = TimeManager.logicTime + interval;
            }
        }

        
        private RpgSummonConfig summonConfig;
        protected void UpdateSummonSkill()
        {
            if (summonConfig == null)
            {
                return;
            }

            if (summonConfig.type == 0)
            {
                UpdateSummonMonsterSkill();
            }
            else if (summonConfig.type == 1)
            {
                UpdateSummonObstacleSkill();
            }
        }
        
        private void UpdateSummonMonsterSkill()
        {
            for (int i = 0; i < summonConfig.positions.Count; i++)
            {
                if (!summonStates[i] && currentTime - stateStartTime >= summonConfig.positions[i].z / 30)
                {
                    var forward = unit.Data.team == 0 ? Vector3.right : Vector3.left;
                    var offset = Quaternion.AngleAxis(PveUtils.GetAngle(forward,Vector3.forward),Vector3.up) * new Vector3(summonConfig.positions[i].x / 1000f,0,summonConfig.positions[i].y / 1000f);
                    UnitManager.Instance.DynamicCreateUnit(summonConfig.id,summonConfig.summon_id,i,globalSkillIndex,unit.Data.team,targetPosition + offset,forward,unit,level);
                    if (summonConfig.summon_effect != 0)
                    {
                        var effect = PveEffectManager.Instance.PlayEffect2(summonConfig.summon_effect,targetPosition + offset + new Vector3(0,3f,0),-PveCameraManager.Instance.rpgMainCamera.transform.forward);
                        if (effect != null)
                        {
                            SetEffectLayer(effect,targetLayer);
                            float endTime = 5 + currentTime;
                            var effectConfig = PveUtils.GetRpgEffectConfig(summonConfig.summon_effect);
                            effectList.Add(new SkillEffectData
                            {
                                effect = effect,
                                effectId = effectId,
                                endTime = endTime,
                                effectController = effect.GetComponent<PveEffectController>(),
                                effectConfig = effectConfig,
                            });
                        }
                    }
                    summonStates[i] = true;
                }
            }
        }

        private void UpdateSummonObstacleSkill()
        {
            for (int i = 0; i < summonConfig.positions.Count; i++)
            {
                if (!summonStates[i] && currentTime - stateStartTime >= summonConfig.positions[i].z / 30)
                {
                    var forward = unit.Data.team == 0 ? Vector3.right : Vector3.left;
                    var offset = Quaternion.AngleAxis(PveUtils.GetAngle(forward,Vector3.forward),Vector3.up) * new Vector3(summonConfig.positions[i].x / 1000f,0,summonConfig.positions[i].y / 1000f);
                    UnitManager.Instance.DynamicCreateObstacle(summonConfig.id,summonConfig.summon_id,unit.Data.team,targetPosition + offset,forward,unit,level);
                    summonStates[i] = true;
                }
            }
        }
        
        protected virtual void UpdateEffect()
        {
            if (this.State == ESkillState.None || this.State == ESkillState.Recover)
            {
                return;
            }

            for (int i = 0; i < childSkills.Count; i++)
            {
                UpdateEffect(childSkills[i].config);
                UpdateSound(childSkills[i].config);
            }
        }

        /// <summary>
        /// 添加额外元素
        /// </summary>
        /// <param name="bulletId"></param>要添加的子弹id
        /// <param name="elementId"></param>要添加的元素id
        /// <param name="action"></param>0添加  1删除
        public void ChangeExtraElement(int bulletId, int elementId,int action)
        {
            if (action == 0) //添加
            {
                if (!extraElements.ContainsKey(bulletId) && !extraElements.ContainsValue(elementId))
                {
                    extraElements.Add(bulletId, elementId);
                }
            } 
            else //删除
            {
                if (extraElements.ContainsKey(bulletId) && extraElements.ContainsValue(elementId))
                {
                    extraElements.Remove(bulletId);
                }
            }
        }

        public void Pause()
        {
            for (int i = 0; i < bulletList.Count; i++)
            {
                bulletList[i].Pause();
            }
        }

        public void Resume()
        {
            for (int i = 0; i < bulletList.Count; i++)
            {
                bulletList[i].Resume();
            }
        }
        
        /// <summary>
        /// 修改元素
        /// </summary>
        /// <param name="bulletId"></param>要修改的子弹id
        /// <param name="oldElementId"></param>旧元素
        /// <param name="newElementId"></param>新元素
        public void ChangeSpecificElement(int bulletId, int oldElementId,int newElementId)
        {
            changeElements[bulletId] = new Vector2Int(oldElementId,newElementId); 
        }


        public void ChangeSpecificBullet(int oldBulletId,int newBulletId,int action)
        {
            if (action == 0)
            {
                changeBullets[oldBulletId] = newBulletId;
            }
            else
            {
                changeBullets.Remove(oldBulletId);
            }
        }

        public void SetLayer(int layer)
        {
            unit.SetLayer(layer);
            /*for (int i = 0; i < targetList.Count; i++)
            {
                targetList[i].SetLayer(layer);
            }*/

            for (int i = 0; i < bulletList.Count; i++)
            {
                bulletList[i].SetLayer(layer);
            }

            for (int i = 0; i < effectList.Count; i++)
            {
                var controller = effectList[i].effectController;
                if (controller)
                {
                    controller.SetLayer(layer);
                }
                else
                {
                    effectList[i].effect.SetLayerRecursively(layer);
                }
            }
            targetLayer = layer;
        }

        protected void ShowBulletCase(Vector3 pos,int bulletId,int bulletIndex)
        {
            var bulletCasePos = pos;
            var bulletCaseForward = Vector3.forward;
            bool showBulletCase = true;
            if (unit.Data.bulletCasePoints.Count > bulletIndex)
            {
                bulletCasePos = unit.Data.bulletCasePoints[(int) bulletIndex].position;
                bulletCaseForward = unit.Data.bulletCasePoints[(int) bulletIndex].forward;
            }
            else if (unit.Data.bulletCasePoints.Count > 0)
            {
                bulletCasePos = unit.Data.bulletCasePoints[0].position;
                bulletCaseForward = unit.Data.bulletCasePoints[0].forward;
            }
            else
            {
                showBulletCase = false;
            }

            if (showBulletCase)
            {
                var bulletConfig = PveUtils.GetSkillBulletConfig(bulletId);
                if (bulletConfig.bullet_case_effect_id == 0)
                {
                    return;
                }
                var bulletCase =
                    PveResourceManager.GetResource(PveResourceManager.EPveResType.Bullet, bulletConfig.bullet_case_effect_id);
                if (bulletCase != null)
                {
                    bulletCase.transform.SetParent(PveScene.pveRootTrans);
                    bulletCase.transform.position = bulletCasePos;
                    bulletCase.transform.forward = bulletCaseForward;
                    bulletCase.transform.localEulerAngles += new Vector3(0,Random.Range(-30,30),0);
                    TimeManager.Instance.DelayCall(2000, () =>
                    {
                        PveResourceManager.RecoverResource(bulletCase,PveResourceManager.EPveResType.Bullet, bulletConfig.bullet_case_effect_id);
                    });
                }
            }


        }
    }
}
